# -*- coding: utf-8 -*-
import sys

sys.path.append('/root/anaconda3/lib/python3.6/site-packages')

from multiprocessing import Process
from pymongo import MongoClient
from bs4 import BeautifulSoup

import jieba.posseg as pseg
import requests
import datetime
import random
import pprint
import time


def token(text):
    return [(tok, pos) for tok, pos in pseg.lcut(text.lower()) if pos not in ['x', 'uj', 'm', 'c'] and len(tok) > 1]


class LIEPIN_POSITION():
    def __init__(self, keywords):
        random.shuffle(keywords)

        for kw in keywords:
            for page in range(100):
                print('kw: %s' % kw)
                print('pg: %d' % page)

                if not self.parse_position_list(kw, page):
                    break

    def parse_position_list(self, keyword, page):
        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8,en-US;q=0.7',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Host': 'www.liepin.com',
            'Pragma': 'no-cache',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
        }

        url = 'https://www.liepin.com/zhaopin/?init=-1&fromSearchBtn=2&key=' + keyword + '&d_sfrom=search_fp&d_pageSize=50&curPage=' + str(page)

        try:
            r = requests.get(url, headers = headers)
        except:
            time.sleep(3)
            return self.parse_position_list(keyword, page)

        soup = BeautifulSoup(r.text, 'lxml')

        if not soup.select('.sojob-list li'):
            return 0

        for item in soup.select('.sojob-list li'):
            self.parse_position_content(item.find(class_ = 'job-info').find('a').get('href'))
            time.sleep(2)

        return 1

    def parse_position_content(self, url):
        if not 'www.liepin.com/job/' in url:
            return

        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'en,zh-CN;q=0.9,zh;q=0.8,en-US;q=0.7',
            'Cache-Control': 'no-cache',
            'Connection': 'keep-alive',
            'Host': 'www.liepin.com',
            'Pragma': 'no-cache',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'
        }

        try:
            r = requests.get(url, headers = headers)
        except:
            return

        soup = BeautifulSoup(r.text, 'lxml')

        name = soup.find('h1').get_text()

        description = soup.find(class_ = 'job-description').find(class_ = 'content').get_text().strip()
        company = soup.find(class_ = 'company-logo').find('p').get_text().strip()

        item = {
            'platform': 'liepin',
            'name': soup.find('h1').get_text(),
            'location': '',
            'stime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'company': soup.find(class_ = 'company-logo').find('p').get_text().strip(),
            'date': soup.find(class_ = 'basic-infor').find('time').get('title').strip(),
            'description': soup.find(class_ = 'job-description').find(class_ = 'content').get_text().strip()
        }

        if not name or not description or not company:
            return

        if not qushu_qiancheng_position.find_one({'name': item['name'], 'company': item['company']}):
            pprint.pprint(item)
            item['token'] = token(item['description'])
            qushu_qiancheng_position.insert_one(item)


def start(keywords):
    LIEPIN_POSITION(keywords)


tech_keywords = [
    'Java',
    'PHP',
    'web前端',
    '后端开发',
    'Java',
    'C++',
    'PHP',
    '数据挖掘',
    'C',
    'C#',
    '.NET',
    'Hadoop',
    'Python',
    'Delphi',
    'VB',
    'Perl',
    'Ruby',
    'Node.js',
    '搜索算法',
    'Golang',
    '自然语言处理',
    '推荐算法',
    'Erlang',
    '算法工程师',
    '语音/视频/图形开发',
    '数据采集',
    '移动开发',
    'HTML5',
    'Android',
    'iOS',
    'WP',
    '移动web前端',
    'Flash',
    'JavaScript',
    'U3D',
    'COCOS2DX',
    '测试工程师',
    '自动化测试',
    '功能测试',
    '性能测试',
    '测试开发',
    '移动端测试',
    '游戏测试',
    '硬件测试',
    '软件测试',
    '运维工程师',
    '运维开发工程师',
    '网络工程师',
    '系统工程师',
    'IT技术支持',
    '系统管理员',
    '网络安全',
    '系统安全',
    'DBA',
    '数据',
    'ETL工程师',
    '数据仓库',
    '数据开发',
    '数据挖掘',
    '数据分析师',
    '数据架构师',
    '算法研究员',
    '项目经理',
    '项目主管',
    '项目助理',
    '项目专员',
    '实施顾问',
    '实施工程师',
    '需求分析工程师',
    '硬件',
    '嵌入式',
    '自动化',
    '单片机',
    '电路设计',
    '驱动开发',
    '系统集成',
    'FPGA开发',
    'DSP开发',
    'ARM开发',
    'PCB工艺',
    '模具设计',
    '热传导',
    '材料工程师',
    '精益工程师',
    '射频工程师',
    '前端开发',
    'web前端',
    'Javascript',
    'Flash',
    'HTML5',
    '通信技术工程师',
    '通信研发工程师',
    '数据通信工程师',
    '移动通信工程师',
    '电信网络工程师',
    '电信交换工程师',
    '有线传输工程师',
    '无线射频工程师',
    '通信电源工程师',
    '通信标准化工程师',
    '通信项目专员',
    '通信项目经理',
    '核心网工程师',
    '通信测试工程师',
    '通信设备工程师',
    '光通信工程师',
    '光传输工程师',
    '光网络工程师',
    '电子工程师',
    '电气工程师',
    'FAE',
    '电气设计工程师',
    '高端技术职位',
    '技术经理',
    '技术总监',
    '测试经理',
    '架构师',
    'CTO',
    '运维总监',
    '技术合伙人',
    '人工智能',
    '机器学习',
    '深度学习',
    '图像算法',
    '图像处理',
    '语音识别',
    '图像识别',
    '算法研究员',
    '软件销售支持',
    '售前工程师',
    '售后工程师',
    '其他技术职位',
    '产品经理',
    '产品总监',
    '产品经理',
    '网页产品经理',
    '移动产品经理',
    '产品助理',
    '数据产品经理',
    '电商产品经理',
    '游戏策划',
    '产品专员',
    '高端产品职位',
    '产品总监',
    '游戏制作人',
    '产品VP',
    '其他产品职位',
    'UI设计师',
    '平面设计师',
    '视觉设计',
    '视觉设计师',
    '网页设计师',
    'Flash设计师',
    'APP设计师',
    'UI设计师',
    '平面设计师',
    '美术设计师（2D/3D）',
    '广告设计师',
    '多媒体设计师',
    '原画师',
    '游戏特效',
    '游戏界面设计师',
    '游戏场景',
    '游戏角色',
    '游戏动作',
    '三维/CAD/制图',
    '美工',
    '包装设计',
    '设计师助理',
    '动画设计师',
    '插画师',
    '交互设计师',
    '无线交互设计师',
    '网页交互设计师',
    '硬件交互设计师',
    '数据分析师',
    '用户研究员',
    '游戏数值策划',
    'UX设计师',
    '用户研究经理',
    '用户研究总监',
    '高端设计职位',
    '设计经理/主管',
    '设计总监',
    '视觉设计经理',
    '视觉设计总监',
    '交互设计经理/主管',
    '交互设计总监',
    '非视觉设计',
    '服装设计',
    '工业设计',
    '橱柜设计',
    '家具设计',
    '家居设计',
    '珠宝设计',
    '室内设计',
    '陈列设计',
    '景观设计',
    '其他设计职位',
    '新媒体运营',
    '产品运营',
    '运营',
    '用户运营',
    '产品运营',
    '数据运营',
    '内容运营',
    '活动运营',
    '商家运营',
    '品类运营',
    '游戏运营',
    '网络推广',
    '网站运营',
    '新媒体运营',
    '社区运营',
    '微信运营',
    '微博运营',
    '策略运营',
    '线下拓展运营',
    '电商运营',
    '运营助理/专员',
    '内容审核',
    '销售运营',
    '编辑',
    '副主编',
    '内容编辑',
    '文案策划',
    '网站编辑',
    '记者',
    '采编',
    '售前咨询',
    '售后咨询',
    '网络客服',
    '客服经理',
    '客服专员/助理',
    '客服主管',
    '客服总监',
    '电话客服',
    '咨询热线/呼叫中心客服',
    '高端运营职位',
    '主编',
    '运营总监',
    'COO',
    '客服总监',
    '运营经理/主管',
    '其他运营职位',
    '市场营销',
    '市场推广',
    '选址开发',
    '市场营销',
    '市场策划',
    '市场顾问',
    '市场推广',
    'SEO',
    'SEM',
    '商务渠道',
    '商业数据分析',
    '活动策划',
    '网络营销',
    '海外市场',
    '政府关系',
    'APP推广',
    '公关媒介',
    '媒介经理',
    '广告协调',
    '品牌公关',
    '媒介专员',
    '活动策划执行',
    '媒介策划',
    '会务会展',
    '会议活动销售',
    '会议活动策划',
    '会议活动执行',
    '会展活动销售',
    '会展活动策划',
    '会展活动执行',
    '广告',
    '广告创意',
    '美术指导',
    '广告设计师',
    '策划经理',
    '文案',
    '广告制作',
    '媒介投放',
    '媒介合作',
    '媒介顾问',
    '广告审核',
    '高端市场职位',
    '市场总监',
    'CMO',
    '公关总监',
    '媒介总监',
    '创意总监',
    '其他市场职位',
    '人事/HR',
    '行政',
    '财务',
    '人力资源主管',
    '招聘',
    'HRBP',
    '人力资源专员/助理',
    '培训',
    '薪资福利',
    '绩效考核',
    '人力资源经理',
    '人力资源VP/CHO',
    '人力资源总监',
    '员工关系',
    '组织发展',
    '行政专员/助理',
    '前台',
    '行政主管',
    '经理助理',
    '后勤',
    '商务司机',
    '行政经理',
    '行政总监',
    '财务',
    '会计',
    '出纳',
    '财务顾问',
    '结算',
    '税务',
    '审计',
    '风控',
    '财务经理',
    'CFO',
    '财务总监',
    '财务主管',
    '法务专员/助理',
    '律师',
    '专利',
    '法律顾问',
    '法务主管',
    '法务经理',
    '法务总监',
    '其他职能职位',
    'CEO/总裁/总经理',
    '高级管理职位',
    'CEO/总裁/总经理',
    '副总裁/副总经理',
    '事业部负责人',
    '区域/分公司/代表处负责人',
    '总裁/总经理/董事长助理',
    '合伙人',
    '创始人',
    '董事会秘书',
    '销售专员',
    '销售经理',
    '销售',
    '销售专员',
    '销售经理',
    '客户代表',
    '大客户代表',
    'BD经理',
    '商务渠道',
    '渠道销售',
    '代理商销售',
    '销售助理',
    '电话销售',
    '销售顾问',
    '商品经理',
    '广告销售',
    '网络营销',
    '营销主管',
    '销售工程师',
    '客户经理',
    '销售管理',
    '销售总监',
    '商务总监',
    '区域总监',
    '城市经理',
    '销售VP',
    '团队经理',
    '其他销售职位',
    '文案',
    '广告创意',
    '编辑',
    '采编/写作/出版',
    '记者',
    '编辑',
    '采编',
    '撰稿人',
    '出版发行',
    '校对录入',
    '总编',
    '自媒体',
    '公关媒介',
    '媒介经理',
    '媒介专员',
    '广告协调',
    '品牌公关',
    '活动策划执行',
    '媒介策划',
    '会务会展',
    '会议活动销售',
    '会议活动策划',
    '会议活动执行',
    '会展活动销售',
    '会展活动策划',
    '会展活动执行',
    '广告',
    '广告创意',
    '美术指导',
    '广告设计师',
    '策划经理',
    '文案',
    '广告制作',
    '媒介投放',
    '媒介合作',
    '媒介顾问',
    '广告审核',
    '影视媒体',
    '助理',
    '统筹制片人',
    '执行制片人',
    '导演/编导',
    '摄影/影像师',
    '视频编辑',
    '音频编辑',
    '经纪人',
    '后期制作',
    '影视制作',
    '影视发行',
    '影视策划',
    '主持人/主播/DJ',
    '演员/配音/模特',
    '化妆/造型/服装',
    '放映管理',
    '录音/音效',
    '制片人',
    '编剧',
    '其他传媒职位',
    '投资经理',
    '投资总监',
    '风控',
    '投融资',
    '投资经理',
    '行业研究',
    '资产管理',
    '投资总监',
    '投资VP',
    '投资合伙人',
    '融资',
    '并购',
    '投后管理',
    '投资助理',
    '其他投融资职位',
    '投资顾问',
    '风控',
    '律师',
    '资信评估',
    '合规稽查',
    '审计',
    '法务',
    '会计',
    '清算',
    '银行',
    '信用卡销售',
    '分析师',
    '柜员',
    '商务渠道',
    '大堂经理',
    '理财顾问',
    '客户经理',
    '信贷管理',
    '风控',
    '互联网金融',
    '金融产品经理',
    '风控',
    '催收员',
    '分析师',
    '投资经理',
    '交易员',
    '理财顾问',
    '合规稽查',
    '审计',
    '清算',
    '保险业务',
    '精算师',
    '保险理赔',
    '证券',
    '证券经纪人',
    '证券分析师',
    '其他金融职位',
    '汽车销售',
    '汽车维修',
    '汽车设计',
    '车身设计',
    '底盘设计',
    '机械设计',
    '动力系统设计',
    '电子工程设计',
    '零部件设计',
    '汽车工程项目管理',
    '内外饰设计工程师',
    '总装工程师',
    '焊接工程师',
    '冲压工程师',
    '质量工程师',
    '汽车销售与制造',
    '汽车销售',
    '汽车配件销售',
    '汽车售后服务',
    '汽车维修',
    '汽车美容',
    '汽车定损理赔',
    '二手车评估师',
    '4S店管理',
    '汽车改装工程师',
    '其他汽车职位',
    '课程设计',
    '教务管理',
    '教育产品研发',
    '课程设计',
    '课程编辑',
    '教师',
    '培训研究',
    '培训师',
    '培训策划',
    '其他教育产品研发职位',
    '教育行政',
    '校长',
    '教务管理',
    '教学管理',
    '班主任/辅导员',
    '教师',
    '助教',
    '高中教师',
    '初中教师',
    '小学教师',
    '幼教',
    '理科教师',
    '文科教师',
    '外语教师',
    '音乐教师',
    '美术教师',
    '体育教师',
    '就业老师',
    'IT培训',
    'JAVA培训讲师',
    'Android培训讲师',
    'ios培训讲师',
    'PHP培训讲师',
    '.NET培训讲师',
    'C++培训讲师',
    'Unity 3D培训讲师',
    'Web前端培训讲师',
    '软件测试培训讲师',
    '动漫培训讲师',
    'UI设计培训讲师',
    '财会培训讲师',
    'HR培训讲师',
    '培训师',
    '拓展培训',
    '课程顾问',
    '招生顾问',
    '留学顾问',
    '教练',
    '舞蹈教练',
    '瑜伽教练',
    '瘦身顾问',
    '游泳教练',
    '健身教练',
    '篮球/羽毛球教练',
    '跆拳道教练',
    '其他教育培训职位',
    '药剂师',
    '营养师',
    '医生/医技',
    '医生助理',
    '医学影像',
    'B超医生',
    '中医',
    '医师',
    '心理医生',
    '药剂师',
    '牙科医生',
    '康复治疗师',
    '验光师',
    '放射科医师',
    '检验科医师',
    '医师',
    '其他医生职位',
    '护士长',
    '护士/护理',
    '导医',
    '健康整形',
    '营养师',
    '整形师',
    '理疗师',
    '针灸推拿',
    '生物制药',
    '药品注册',
    '药品生产',
    '临床研究',
    '临床协调',
    '临床数据分析',
    '医学总监',
    '医药研发',
    '医疗器械注册',
    '医疗器械生产/质量管理',
    '医疗器械研究',
    '药店',
    '店长',
    '执业药师/驻店药师',
    '店员/营业员',
    '市场营销/媒体',
    '医疗器械销售',
    '医学编辑',
    '医学总监',
    '药学编辑',
    '医药代表',
    '健康顾问',
    '医美咨询',
    '其他医疗健康类职位',
    '采购经理',
    '采购主管',
    '采购',
    '采购总监',
    '采购经理',
    '采购专员',
    '买手',
    '采购工程师',
    '采购主管',
    '采购助理',
    '进出口贸易',
    '外贸经理',
    '外贸专员',
    '外贸业务员',
    '贸易跟单',
    '其他采购/贸易类职位',
    '物流专员',
    '贸易跟单',
    '物流',
    '供应链专员',
    '供应链经理',
    '物流专员',
    '物流经理',
    '物流运营',
    '物流跟单',
    '贸易跟单',
    '物仓调度',
    '物仓项目',
    '运输经理/主管',
    '货运代理专员',
    '货运代理经理',
    '水/空/陆运操作',
    '报关员',
    '报检员',
    '核销员',
    '单证员',
    '仓储',
    '仓储物料经理',
    '仓储物料专员',
    '仓储物料项目',
    '仓储管理',
    '仓库文员',
    '配/理/拣/发货',
    '运输',
    '货运司机',
    '集装箱管理',
    '配送',
    '快递',
    '高端供应链职位',
    '供应链总监',
    '物流总监',
    '其他供应链职位',
    '物业管理',
    '房地产规划开发',
    '房产策划',
    '地产项目管理',
    '地产招投标',
    '设计装修与市政建设',
    '高级建筑工程师',
    '建筑工程师',
    '建筑设计师',
    '土木/土建/结构工程师',
    '室内设计',
    '园林设计',
    '城市规划设计',
    '工程监理',
    '工程造价',
    '预结算',
    '工程资料管理',
    '建筑施工现场管理',
    '房地产经纪',
    '地产置业顾问',
    '地产评估',
    '地产中介',
    '物业管理',
    '物业租赁销售 ',
    '物业招商管理',
    '高端房地产职位',
    '地产项目总监',
    '地产策划总监',
    '地产招投标总监',
    '物业总监',
    '房地产销售总监',
    '其他房地产职位',
    '企业管理咨询',
    '咨询/调研',
    '企业管理咨询',
    '数据分析师',
    '财务咨询顾问',
    'IT咨询顾问',
    '人力资源顾问',
    '咨询项目管理',
    '战略咨询',
    '猎头顾问',
    '市场调研',
    '咨询顾问',
    '知识产权',
    '事务所律师',
    '公司法务',
    '英语翻译',
    '日语翻译',
    '韩语/朝鲜语翻译',
    '法语翻译',
    '德语翻译',
    '俄语翻译',
    '西班牙语翻译',
    '咨询总监',
    '咨询经理',
    '高级翻译',
    '同声传译  ',
    '实习生',
    '管培生',
    '实习生',
    '管理培训生',
    '储备干部',
    '旅游顾问',
    '导游',
    '旅游服务',
    '计调',
    '签证',
    '旅游顾问',
    '导游',
    '预定票务',
    '产品经理',
    '旅游策划师',
    '其他旅游职位',
    '酒店前台',
    '客房服务员',
    '店员/营业员',
    '门店店长',
    '发型师',
    '美甲师',
    '化妆师',
    '健身',
    '瑜伽教练',
    '瘦身顾问',
    '游泳教练',
    '美体教练',
    '美容师/顾问',
    '舞蹈教练',
    '健身教练',
    '生产总监',
    '安全员',
    '生产营运',
    '厂长/工厂经理',
    '生产总监',
    '生产经理/车间主任',
    '生产组长/拉长',
    '生产员',
    '生产设备管理',
    '生产计划/物料控制',
    '生产跟单',
    '质量管理/测试',
    '可靠度工程师',
    '故障分析师',
    '认证工程师',
    '体系工程师',
    '审核员',
    '安全员',
    '机械设计/制造',
    '机械工程师',
    '机械设计师',
    '机械设备工程师',
    '机械维修/保养',
    '机械制图',
    '机械结构工程师',
    '工业工程师',
    '工艺/制程工程师',
    '材料工程师',
    '机电工程师',
    'CNC/数控',
    '冲压工程师',
    '夹具工程师',
    '模具工程师',
    '焊接工程师',
    '注塑工程师',
    '铸造/锻造工程师',
    '化工',
    '化工工程师',
    '实验室技术员',
    '化学分析',
    '涂料研发',
    '化妆品研发',
    '服装设计',
    '女装设计',
    '男装设计',
    '童装设计',
    '内衣设计',
]

if __name__ == '__main__':
    from optparse import OptionParser

    parser = OptionParser(usage = "%prog [options]")
    parser.add_option("-p", "--process", action = "store", type = "int", dest = "count", help = "the count of process", default = 5)
    parser.add_option("-e", "--network", action = "store", type = "str", dest = "address", help = "the address of mongodb", default = 'localhost')

    options, args = parser.parse_args()

    client = MongoClient(options.address, 27017, connect = False)

    qushu_qiancheng_db = client['qushu_qiancheng_db']
    qushu_qiancheng_position = qushu_qiancheng_db['qushu_qiancheng_position']

    proc_list = []

    seg = int(len(tech_keywords) / options.count)

    for i in range(options.count):
        p = Process(target = start, args = (tech_keywords[seg * i:seg * (i + 1)],))
        proc_list.append(p)

    for p in proc_list:
        p.start()

    for p in proc_list:
        p.join()
